package com.chaoxing.ai.speech.utils;

import org.springframework.stereotype.Component;

import java.io.File;

/**
 * @author lyf
 * @version 1.0.0
 * @date 2022年06月23日  11:22:30
 * @describe 功能
 */
@Component
public class FFmpegAudioUtil {

    /**
     * m4a格式转换为wav格式
     * @param filePath
     * @param newfilePath
     */
    public void ffM4AtoWAV(String filePath,String newfilePath) {
        String webroot = "E:\\ffmpeg\\bin";  //ffmpeg安装路径

        Runtime run = null;
        try {
            run = Runtime.getRuntime();
            long start = System.currentTimeMillis();
            System.out.println(new File(webroot).getAbsolutePath());
            //执行ffmpeg.exe,前面是ffmpeg.exe的地址，中间是需要转换的文件地址，后面是转换后的文件地址。-i是转换方式，意思是可编码解码，mp3编码方式采用的是libmp3lame
            Process p = run.exec(new File(webroot).getAbsolutePath() + "/ffmpeg -y -i " + filePath + " -acodec pcm_s16le -ac 1 -ar 16000 " + newfilePath);
            p.getOutputStream().close();
            p.getInputStream().close();
            p.getErrorStream().close();
            p.waitFor();
            long end = System.currentTimeMillis();
            System.out.println(filePath + " convert success, costs:" + (end - start) + "ms");
        } catch (Exception e) {
            e.printStackTrace();
        }
        //run调用lame解码器最后释放内存
        run.freeMemory();
    }

    /**
     * mp3 文件转 16K 16bits 位深的单声道 pcm文件
     * @param filePath
     * @param newfilePath
     *
     * ffmpeg -y  -i aidemo.mp3  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm
     * // -acodec pcm_s16le pcm_s16le 16bits 编码器
     * // -f s16le 保存为16bits pcm格式
     * // -ac 1 单声道
     * //  -ar 16000  16000采样率
     */
    public void ffMP3toPCM(String filePath,String newfilePath) {
        String webroot = "E:\\ffmpeg\\bin";  //ffmpeg安装路径
        Runtime run = null;
        try {
            run = Runtime.getRuntime();
            long start = System.currentTimeMillis();
            System.out.println(new File(webroot).getAbsolutePath());
            //执行ffmpeg.exe,前面是ffmpeg.exe的地址，中间是需要转换的文件地址，后面是转换后的文件地址。-i是转换方式，意思是可编码解码，mp3编码方式采用的是libmp3lame

            Process p = run.exec(new File(webroot).getAbsolutePath() + "/ffmpeg -i " + filePath + " -f s16le -y " + newfilePath);
            p.getOutputStream().close();
            p.getInputStream().close();
            p.getErrorStream().close();
            p.waitFor();
            long end = System.currentTimeMillis();
            System.out.println(filePath + " convert success, costs:" + (end - start) + "ms");
        } catch (Exception e) {
            e.printStackTrace();
        }
        //run调用lame解码器最后释放内存
        run.freeMemory();
    }

    /**
     * amr转MP3
     * @param sourcePath
     * @param targetPath
     * @throws Exception
     */
    public void ffAmrToMp3(String sourcePath, String targetPath) throws Exception {
        String webroot = "E:\\ffmpeg\\bin";  //ffmpeg安装路径
        Runtime run = null;
        try {
            run = Runtime.getRuntime();
            long start=System.currentTimeMillis();
            System.out.println(new File(webroot).getAbsolutePath());
            //执行ffmpeg.exe,前面是ffmpeg.exe的地址，中间是需要转换的文件地址，后面是转换后的文件地址。-i是转换方式，意思是可编码解码，mp3编码方式采用的是libmp3lame
            //wav转pcm
            //Process p=run.exec(new File(webroot).getAbsolutePath()+"/ffmpeg -y -i "+sourcePath+" -acodec pcm_s16le -f s16le -ac 1 -ar 16000 "+targetPath);
            //mp3转pcm
            Process p=run.exec(new File(webroot).getAbsolutePath()+"/ffmpeg -i "+sourcePath+"  "+targetPath);
            //释放进程
            p.getOutputStream().close();
            p.getInputStream().close();
            p.getErrorStream().close();
            p.waitFor();
            long end=System.currentTimeMillis();
            System.out.println(sourcePath+" convert success, costs:"+(end-start)+"ms");
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //run调用lame解码器最后释放内存
            run.freeMemory();
        }
    }

    /**
     * PCM转WAV 8000
     * @param filePath
     * @param newfilePath
     */
    public void ffPCMtoWAV8K(String filePath,String newfilePath) {
        String webroot = "E:\\ffmpeg\\bin";  //ffmpeg安装路径
        Runtime run = null;
        try {
            run = Runtime.getRuntime();
            long start = System.currentTimeMillis();
            System.out.println(new File(webroot).getAbsolutePath());
            //run.exec(new File(webroot).getAbsolutePath() +"/ffprobe -v quiet -print_format json -show_streams  "+filePath);      //获取音频文件信息
            //执行ffmpeg.exe,前面是ffmpeg.exe的地址，中间是需要转换的文件地址，后面是转换后的文件地址。-i是转换方式，意思是可编码解码，mp3编码方式采用的是libmp3lame
            Process p = run.exec(new File(webroot).getAbsolutePath() + "/ffmpeg -f s16le -ar 8000 -ac 1 -i " + filePath + " " + newfilePath);
            p.getOutputStream().close();
            p.getInputStream().close();
            p.getErrorStream().close();
            p.waitFor();
            long end = System.currentTimeMillis();
            System.out.println(filePath + " convert success, costs:" + (end - start) + "ms");
        } catch (Exception e) {
            e.printStackTrace();
        }
        //run调用lame解码器最后释放内存
        run.freeMemory();
    }

    /**
     * PCM转WAV 16000
     * @param filePath
     * @param newfilePath
     */
    public void ffPCMtoWAV16K(String filePath,String newfilePath) {
        String webroot = "E:\\ffmpeg\\bin";  //ffmpeg安装路径
        Runtime run = null;
        try {
            run = Runtime.getRuntime();
            long start = System.currentTimeMillis();
            System.out.println(new File(webroot).getAbsolutePath());
            //执行ffmpeg.exe,前面是ffmpeg.exe的地址，中间是需要转换的文件地址，后面是转换后的文件地址。-i是转换方式，意思是可编码解码，mp3编码方式采用的是libmp3lame
            Process p = run.exec(new File(webroot).getAbsolutePath() + "/ffmpeg -f s16le -ar 16000 -ac 1 -i " + filePath + " " + newfilePath);
            p.getOutputStream().close();
            p.getInputStream().close();
            p.getErrorStream().close();
            p.waitFor();
            long end = System.currentTimeMillis();
            System.out.println(filePath + " convert success, costs:" + (end - start) + "ms");
        } catch (Exception e) {
            e.printStackTrace();
        }
        //run调用lame解码器最后释放内存
        run.freeMemory();
    }


}

